/*
 * BookFilesPanel.java
 *
 *  created: 7.10.2011
 *  charset: UTF-8
 *  license: MIT (X11) (See LICENSE file for full license)
 */
package cz.mp.k3bg.gui;

import cz.mp.k3bg.Application;
import cz.mp.k3bg.BookState;
import static cz.mp.k3bg.Constants.*;
import cz.mp.k3bg.Images;
import static cz.mp.k3bg.Images.*;
import static cz.mp.k3bg.TextSource.getLocText;
import cz.mp.k3bg.core.BookFiles;
import cz.mp.k3bg.core.ItemImage;
import cz.mp.k3bg.gui.component.FileChooserField;
import cz.mp.k3bg.gui.component.FilesList;
import cz.mp.k3bg.gui.component.LabelForMandatory;
import cz.mp.k3bg.log.LoggerManager;
import cz.mp.util.ImageUtils;
import cz.mp.util.Stopwatch;
import cz.mp.util.StringUtils;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.util.logging.Logger;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import net.miginfocom.swing.MigLayout;

/**
 * Panel pro zadání pracovního adresáře, souborů knihy.
 *
 * @author Martin Pokorný
 * @version 0.1
 * @see MainTabbedPane
 * @see BookFiles
 * @see ImportFilesDialog
 * @see GenerateTocDialog
 * @see GeneratePersonalNotesDialog
 * @see GenerateColophonDialog
 */
public class BookFilesPanel extends TabPanel {

    private static final boolean DEBUG = false;
    private static final Logger logger =
            LoggerManager.getLogger(BookFilesPanel.class, DEBUG);    
    
    private ImageIcon IMG_LISTS = Images.getImage(LISTS_32);

    private JLabel workingDirLabel = new LabelForMandatory(getLocText("gui.bookfiles.working_dir"));
    private FileChooserField workingDirField = new FileChooserField();
    // (poznámka: do workingDirField lze zadat Relativní cestu, mělo by fungovat dobře)
    
    private JButton importFilesButton = new JButton(
            getLocText("gui.bookfiles.import"), 
                Images.getImage(IMPORT));
    
    private JLabel bookFilesLabel = new LabelForMandatory(getLocText("gui.bookfiles.main_files"));
    private FilesList bookFilesList = new FilesList();
            
    private JLabel tocLabel = new LabelForMandatory(getLocText("gui.bookfiles.toc"));
    private FileChooserField tocFileField;
    private JButton tocGenButton = new JButton(
            getLocText("gui.bookfiles.generate"), 
                Images.getImage(GEAR));

    private JLabel loiLabel = new JLabel(getLocText("gui.bookfiles.loi"));
    private FileChooserField loiFileField;

    private JLabel personalsLabel = new JLabel(getLocText("gui.bookfiles.personals"));
    private FileChooserField personalsFileField;
    private JButton personalsGenButton = new JButton(
            getLocText("gui.bookfiles.generate"), 
                Images.getImage(GEAR));

    private JLabel colophonLabel = new JLabel(getLocText("gui.bookfiles.colophon"));
    private FileChooserField colophonFileField;
    private JButton colophonGenButton = new JButton(
            getLocText("gui.bookfiles.generate"), 
                Images.getImage(GEAR));

    private JLabel coverLabel = new LabelForMandatory(getLocText("gui.bookfiles.cover"));
    private FileChooserField coverFileField;
    
    private boolean isDefinedWorkingDir = false;
    
    // -----

    /** */
    public BookFilesPanel() {
        super();
        initComponents();
        initLayout();
        initEventHandlers();
    }
    
    
    /** */
    private void initComponents() {

        workingDirLabel.setLabelFor(workingDirField);
        tocLabel.setLabelFor(tocFileField);
        loiLabel.setLabelFor(loiFileField);
        personalsLabel.setLabelFor(personalsFileField);
        colophonLabel.setLabelFor(colophonFileField);
        coverLabel.setLabelFor(coverFileField);
        bookFilesLabel.setLabelFor(bookFilesList);
        
        importFilesButton.setToolTipText(getLocText("gui.bookfiles.import.tooltip"));

        // ---
                
        workingDirField.clear();
        
        tocFileField = new FileChooserField();        
        tocFileField.setFilter(HTML_FILEFILTER);
        tocFileField.clear();
        
        loiFileField = new FileChooserField();
        loiFileField.setFilter(HTML_FILEFILTER);
        loiFileField.clear();
        
        personalsFileField = new FileChooserField();
        personalsFileField.setFilter(HTML_FILEFILTER);
        personalsFileField.clear();
                
        colophonFileField = new FileChooserField();
        colophonFileField.setFilter(HTML_FILEFILTER);
        colophonFileField.clear();
        
        coverFileField = new FileChooserField();
        coverFileField.setFilter(COVER_FILEFILTER);
        coverFileField.clear();

        workingDirField.setSelectionMode(JFileChooser.DIRECTORIES_ONLY);        
        if (Application.OS_IS_WINDOWS) {
            workingDirLabel.setText(getLocText("gui.bookfiles.working_dir.windows"));
        }
        
        bookFilesList.setFilter(HTML_FILEFILTER);
    }

    /** */
    private void initLayout() {
        this.setLayout(new MigLayout("",//"debug"
                "unrel[label]rel[fill,grow]rel[]rel[]rel[]rel[]unrel",
                "unrel[]rel[]"));

        this.add(workingDirLabel);
        this.add(workingDirField, "spanx 3, sgy");
        this.add(importFilesButton, "span, sgy, gapleft rel, wrap 2.5*para");
       
        this.add(bookFilesLabel, "top");

        this.add(bookFilesList, "spanx 3, wrap unrel");
        
        this.add(tocLabel);
        this.add(tocFileField, "spanx 3, sgy");
        this.add(tocGenButton, "skip, wrap");

        this.add(loiLabel);
        this.add(loiFileField, "spanx 3, sgy, wrap");

        this.add(personalsLabel);
        this.add(personalsFileField, "spanx 3, sgy");
        this.add(personalsGenButton, "skip, wrap");

        this.add(colophonLabel);
        this.add(colophonFileField, "spanx 3, sgy");
        this.add(colophonGenButton, "skip, wrap");

        this.add(coverLabel);
        this.add(coverFileField, "spanx 3, sgy, wrap 2*para");
                
        this.add(statusPanel, "spanx, grow");
    }

    /** */
    private void initEventHandlers() {

        bookFilesList.addChangeListener(new ChangeListener() {
            @Override
            public void stateChanged(ChangeEvent e) {
                update();
            }
        });

        tocGenButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                generateToc();
            }
        });

        colophonGenButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                generateColophon();
            }
        });
        
        personalsGenButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                generatePersonalNotes();
            }
        });
                
        coverFileField.addChangeListener(new ChangeListener() {
            @Override
            public void stateChanged(ChangeEvent e) {
                update();
            }
        });

        importFilesButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                
                if (workingDirField.isSelectedFile()) {                
                    ImportFilesDialog.showDialog(workingDirField.getSelectedFilePath());
                }
            }
        });

        workingDirField.addChangeListener(new ChangeListener() {
            String oldValue = "";

            @Override
            public void stateChanged(ChangeEvent e) {

                SwingUtilities.invokeLater(
                    new Runnable() {
                        @Override
                        public void run() {

                            String value = workingDirField.getSelectedFilePath();
                            if (! oldValue.equals(value) &&
                                    workingDirField.isSelectedFile()) {
                                logger.fine("(workingDirField) stateChanged");                                
                                
                                setRootToFields(
                                        workingDirField.getSelectedFilePath());
                                
                                oldValue = value;
                            }
                            update();
                        }
                    });
            }

        });
    }

    /**
     * 
     * @param rootPath 
     */
    private void setRootToFields(String rootPath) {
        logger.fine("rootPath = " + rootPath);
        
        bookFilesList.setRoot(rootPath);
        tocFileField.setRoot(rootPath);
        loiFileField.setRoot(rootPath);
        personalsFileField.setRoot(rootPath);
        colophonFileField.setRoot(rootPath);
        coverFileField.setRoot(rootPath);        
    }
    

    @Override
    public void clear() {
        logger.fine("");
        
        SwingUtilities.invokeLater(
            new Runnable() {
                @Override
                public void run() {
                    workingDirField.clear();

                    setRootToFields(null);

                    update();
                }
            });        
    }


    /**
     * 
     */
    BookFiles createBookFiles() {
        BookFiles result = null;

        Stopwatch stopwatch = new Stopwatch();
        stopwatch.start();
        
        if (workingDirField.isSelectedFile()
                && ! bookFilesList.getFiles().isEmpty()
                && tocFileField.isSelectedFile()
                && coverFileField.isSelectedFile()
                ) {
            result = new BookFiles(
                    workingDirField.getSelectedFileAbsolutePath());
            try {
                result.addSrcFiles(bookFilesList.getFiles());
                result.setToc(tocFileField.getSelectedFilePath());
                result.setLoi(loiFileField.getSelectedFilePath());
                result.setPersonalNotes(personalsFileField.getSelectedFilePath());
                result.setColophon(colophonFileField.getSelectedFilePath());
                result.setCoverImage(coverFileField.getSelectedFilePath());
            } catch (IOException ex) {
                logger.warning(ex.toString());
                if (DEBUG) {  ex.printStackTrace();  }            
                Dialogs.showErrorDialog(ex);
            }
        }

        stopwatch.stop();
        logger.info("  " + stopwatch.getTimeMs() + " ms");
                
        return result;
    }

    /**
     *
     */
    private void generateToc() {

        if (workingDirField.isSelectedFile()
                && ! bookFilesList.getFiles().isEmpty()) {
            BookFiles bookFilesForToc = new BookFiles(
                    workingDirField.getSelectedFileAbsolutePath());

            try {
                bookFilesForToc.addSrcFiles(bookFilesList.getFiles());

                String generatedFile =
                        GenerateTocDialog.showDialog(bookFilesForToc);

                if (! StringUtils.isBlank(generatedFile)) {
                    tocFileField.setSelectedFile(generatedFile);
                }

            } catch (IOException ex) {
                logger.warning(ex.toString());
                if (DEBUG) {  ex.printStackTrace();  }
                Dialogs.showErrorDialog(ex);
            }
        }
    }

    /**
     *
     */
    private void generatePersonalNotes() {
        BookFiles bookFilesForPn = new BookFiles(
                workingDirField.getSelectedFileAbsolutePath());

        String generatedFile =
                GeneratePersonalNotesDialog.showDialog(bookFilesForPn);

        if (! StringUtils.isBlank(generatedFile)) {
            personalsFileField.setSelectedFile(generatedFile);
        }
    }
    
    /**
     * 
     */
    private void generateColophon() {
        BookFiles bookFilesForColophon = new BookFiles(
                workingDirField.getSelectedFileAbsolutePath());

        String generatedFile =
                GenerateColophonDialog.showDialog(bookFilesForColophon);

        if (! StringUtils.isBlank(generatedFile)) {
            colophonFileField.setSelectedFile(generatedFile);
        }
    }


    @Override
    public ImageIcon getImageIcon() {
        return IMG_LISTS;
    }

    @Override
    public String getTitle() {
        return getLocText("gui.maintabpane.bookfiles");
    }

    @Override
    public void update() {
        isDefinedWorkingDir = workingDirField.isSelectedFile();
        
        if (workingDirField.isEmpty()) {
            disableAllExcept(workingDirLabel, workingDirField);
        }
        else {
            enabledAll();
        }

        updateStatusPanel();
        
        updateButtons();
    }
    
    /**
     * 
     */
    private void updateStatusPanel() {
        statusPanel.clear();

//        if (! workingDirField.isSelectedFile()) {
        if (workingDirField.isEmpty()) {
            // Kódování textu zdrojových souborů by mělo být UTF-8
            statusPanel.addNote(
                    getLocText("gui.bookfiles.status.note_src_in_utf8"));
        }
        
        String imagePath = coverFileField.getSelectedFileAbsolutePath();
        if (! StringUtils.isBlank(imagePath) 
                && coverFileField.isSelectedFile()) {
            Dimension coverSize = ImageUtils.getImageSize(imagePath);
            if (coverSize != null && ! ItemImage.isGoodKindle3BookCover(
                    coverSize.width, coverSize.height)) {
                // Obrázek obálky nemá doporučenou velikost
                statusPanel.addWarning(
                        getLocText("gui.bookfiles.status.warn_cover_size", 
                            coverSize.width, coverSize.height));
            }
        }        
    }
    
    /**
     * 
     */
    private void updateTocGenButton() {
        boolean canBeGeneratedToc = isDefinedWorkingDir
                && ! bookFilesList.getFiles().isEmpty();
        tocGenButton.setEnabled(canBeGeneratedToc);
        
        if (isDefinedWorkingDir
                && bookFilesList.getFiles().isEmpty()) {
            tocGenButton.setToolTipText(getLocText("gui.bookfiles.gen_toc_button.disabled.tooltip"));
        }
        else {
            tocGenButton.setToolTipText(null);
        }        
    }
    
    /**
     * 
     */
    private void updateColophonGenButton() {
        boolean canBeGeneratedColophon = isDefinedWorkingDir
                && BookState.getMainInstance().getMetadata() != null;
        colophonGenButton.setEnabled(canBeGeneratedColophon);

        if (isDefinedWorkingDir
                && BookState.getMainInstance().getMetadata() == null) {
            colophonGenButton.setToolTipText(getLocText("gui.bookfiles.gen_colophon_button.disabled.tooltip"));
        }
        else {
            colophonGenButton.setToolTipText(null);
        }        
    }
    
    /**
     * 
     */
    private void updateButtons() {
        updateTocGenButton();
        updateColophonGenButton();
        importFilesButton.setEnabled(isDefinedWorkingDir);        
        personalsGenButton.setEnabled(isDefinedWorkingDir);        
    }
    
}   // BookFilesPanel.java
